﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NetMQ;
using NetMQ.Sockets;


namespace IMLibrary.ExZeroMQ
{
    /// <summary>
    /// MQServer
    /// </summary>
    public class MQServer : IDisposable
    {

        public MQServer()
        { }

        public MQServer(int port, ServerType type)
        {
            _type = type;
            _port = port;
            CreateServer();
        }

        #region 事件
        public delegate void ReceiveEventHandler(object sender, MQEventArgs e);

        public event ReceiveEventHandler Receive;

        private void OnReceive(MQEventArgs e)
        {
            if (Receive != null)
                Receive(this, e);
        }
        #endregion

        #region 字段
        private int _port;
        private NetMQSocket _socket;
        private ServerType _type;
        private bool _isRead = true;
        private Task _task;
        #endregion

        #region 属性
        public NetMQSocket Socket
        {
            get { return _socket; }
        }
        #endregion

        #region 私有方法
        private void CreateServer()
        {
            switch (_type)
            {
                case ServerType.Response:
                    _socket = new ResponseSocket(); break;
                case ServerType.Pub:
                    _socket = new PushSocket(); break;
                case ServerType.Router:
                    _socket = new RouterSocket(); break;
                case ServerType.Stream:
                    _socket = new StreamSocket(); break;
                case ServerType.Push:
                    _socket = new PushSocket(); break;
                case ServerType.XPub:
                    _socket = new XPublisherSocket(); break;
                default:
                    _socket = new ResponseSocket(); break;
            }
            _socket.Bind("tcp://*:" + _port);
        }

        private void AsyncRead(NetMQSocket _socket)
        {
            while (_isRead)
            {
                try
                {
                    if (_type == ServerType.Router)
                    {
                        var clientID = _socket.ReceiveFrameBytes();
                        var msg = _socket.ReceiveFrameBytes();
                        OnReceive(new MQEventArgs(clientID, msg));
                    }
                    else
                    {
                        var msg = _socket.ReceiveFrameBytes();
                        OnReceive(new MQEventArgs(msg));
                    }
                }
                catch { }
            }
        }
        #endregion
         
        #region 公共方法

        public void StartAsyncReceive()
        {
            if (_task == null)
                _task = Task.Factory.StartNew(() => AsyncRead(_socket), TaskCreationOptions.LongRunning);
        }

        public void Send(byte[] data)
        {
            _socket.SendFrame(data);
        }

        /// <summary>
        /// 如果是Router
        /// </summary>
        /// <param name="clientID"></param>
        /// <param name="data"></param>
        public void Send(byte[] clientID, byte[] data)
        {
            if (_type == ServerType.Router)
                _socket.SendMoreFrame(clientID).SendFrame(data);
            else
                Send(data);
        }

        public void Dispose()
        {
            _isRead = false;
            //if (_task != null)
            //    _task.Dispose();
            _socket.Close();
            _socket.Dispose();

        }
        #endregion
    }
}
